package org.zy;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class RuleAnalysisEngine {

    private static Map<String, Object> riskEngineMap;

    public RuleAnalysisEngine() {
        init(RiskAnalysisRule.get());
    }

    private static void init(Map<String, String> riskAnalysisMap) {
        riskEngineMap = new HashMap<>();
        for (String key : riskAnalysisMap.keySet()) {
            String desc = riskAnalysisMap.get(key);
            Map<String, Calculator> map = analysisGroup(desc);
            riskEngineMap.put(key, map);
        }
//        log.warn("高风险规则数据初始化完成");
    }

    public String read(String key, Object value) {
        Map<String, Object> valueMap = new HashMap<>();
        valueMap.put("x", value);
        Map<String, Calculator> map = (Map<String, Calculator>) riskEngineMap.get(key);
        return cacluate(map, valueMap);
    }

    public void test2() {
        String key = MetricConstants.CPU_AVG_PCT;
        Object value = 0.8f;
        String result = read(key, value);
        System.out.println("analysising "+key+",risk level is "+result);
    }

    public void test1() {
        String s = "x > 0.2,LOW;0.1 < x <= 0.2,MEDIUM;x <= 0.1,HIGH;";
        Map<String, Calculator> map = analysisGroup(s);

        Map<String, Object> valueMap = new HashMap<>();
        Object value = 0.3;
        valueMap.put("x", value);
        System.out.print("input value is: " + value);
        Object result = cacluate(map, valueMap);
        System.out.println(", risk level is: " + result);
    }

    private static String cacluate(Map<String, Calculator> map, Map<String, Object> valueMap) {
        for (String key : map.keySet()) {
            Calculator calculator = map.get(key);
            Object result = calculator.calculate(valueMap);
            if (result instanceof Boolean && (Boolean) result) {
                return key;
            }
        }
        return null;
    }


    private static Map<String, Calculator> analysisGroup(String ruleGroup) {
        Map<String, Calculator> map = new HashMap<>();
        for (String s : ruleGroup.split(";")) {
//            List<String> andList = new ArrayList<>();
            String[] a1 = s.split(",");
            String s1 = a1[0];

            String[] a2 = s1.split("x");
            if (a2[0].isEmpty()) {
                Calculator calculator = parse(s1.substring(1));
                map.put(a1[1], calculator);
            } else {
                AndExpression andExpression = new AndExpression();
                map.put(a1[1], andExpression);
                for (String s3 : a2) {
                    String s4 = s3.trim();
                    if (!startsWithOperator(s4)) {
                        andExpression.setV1(parse(reverse(s4)));
                    } else {
                        andExpression.setV2(parse(s4));
                    }
                }

            }

        }
        return map;
    }

    //操作符提前
    private static String reverse(String s2) {
        String[] s = s2.trim().split(" ");
        if (s.length != 2) {
            throw new RuntimeException("公式不合法");
        }
        String operator;
        if (s[1].startsWith("<")) {
            operator = s[1].replace("<", ">");
        } else if (s[1].startsWith(">")) {
            operator = s[1].replace(">", "<");
        } else {
            operator = s[1];
        }
        String value = s[0];

        return operator + " " + value;
    }

    private static Calculator parse(String s) {
        String[] a = s.trim().split(" ");
        String operator = a[0];
        String value = a[1];
        BigDecimal dValue = null;
        value = value.toLowerCase().replaceAll("k", "*1024").replaceAll("m", "*1024*1024").replaceAll("g", "*1024*1024*1024");
        if (value.indexOf('*') >= 0) {
            String[] vs = value.split("\\*");

            for (String v : vs) {
                String v1 = v.trim();
                if (!v1.isEmpty()) {
                    if (dValue == null) {
                        dValue = new BigDecimal(v1);
                    } else {
                        dValue = new BigDecimal(v1).multiply(dValue);
                    }
                }
            }
        } else {
            dValue = new BigDecimal(value);
        }
        Operator operator1 = null;
        if (operator.equals(">") || operator.equals("GT")) {
            operator1 = Operator.GT;
        } else if (operator.equals(">=") || operator.equals("GE")) {
            operator1 = Operator.GE;
        } else if (operator.equals("<") || operator.equals("LT")) {
            operator1 = Operator.LT;
        } else if (operator.equals("<=") || operator.equals("LE")) {
            operator1 = Operator.LE;
        } else if (operator.equals("=") || operator.equals("EQ")) {
            operator1 = Operator.EQ;
        }
        BooleanExpression booleanExpression = new BooleanExpression(operator1, dValue.toString(), "x");
        return booleanExpression;
    }

    //首字母是操作符
    private static boolean startsWithOperator(String s) {
        String[] ops = new String[]{">", ">=", "=", "<", "<=", "GT", "GE", "LT", "LE", "EQ", "EXISTS", "CONTAINS"};
        for (String op : ops) {
            if (s.startsWith(op)) {
                return true;
            }
        }
        return false;
    }

    private static void format(char[] chars) {
        char[] ops = new char[]{'>', '=', '<'};
        char[] a = new char[1000];
        int j = 0;
        for (int i = 0; i < chars.length - 1; i++) {
            char c = chars[i];

            if (isCharInArray(c, ops) && !isCharInArray(chars[i - 1], ops)) {
                a[j++] = ' ';
                a[j++] = c;
                a[j++] = ' ';
            }
        }
    }

    private static boolean isCharInArray(char aChar, char[] ops) {
        for (char c : ops) {
            if (c == aChar) {
                return true;
            }
        }
        return false;
    }


}
